/**
 * 项目名：	Rumba Plan
 * 
 * 版权所有(C)，上海海鼎信息工程股份有限公司，2006，所有权利保留。
 * 
 * 文件名：	PermExp.java
 * 模块说明：	
 * 修改历史：
 * 2006-6-29 - lxm - 创建。
 */
package com.hd123.rumba.user;

import com.hd123.rumba.exception.BusinessException;

/**
 * 权限表达式(Permission Expression)
 * 
 * @author lxm
 * 
 */
public class PE {

  /**
   * 将指定的权限转换为一个表达式。
   * 
   * @param permissionId 指定的权限ID。允许null，等价于调用PE.TRUE。
   * @return
   * @throws BusinessException
   */
  public static PE P(String permissionId) throws BusinessException {
    if (permissionId == null)
      return TRUE;
    PE pe = new PE();
    pe.operator = new Integer(0);
    pe.permissionId = permissionId;
    return pe;
  }
  
  /**
   * 将一个布尔值转换为一个表达式。
   * 
   * @param boolValue
   * @return
   */
  public static PE B(boolean boolValue) {
    PE pe = new PE();
    pe.operator = new Integer(3);
    pe.boolValue = boolValue;
    return pe;
  }

  /** 常量true对应的表达式 */
  public static final PE TRUE = PE.B(true);
  /** 常量false对应的表达式 */
  public static final PE FALSE = PE.B(false);

  /**
   * And运算。
   * 
   * @param pe1
   * @param pe2
   * @return
   * @throws BusinessException
   */
  public static PE AND(PE pe1, PE pe2) throws BusinessException {
    return PE.build(PE.VALUE_OPERATOR_AND, pe1, pe2);
  }
  
  /**
   * And运算。
   * 
   * @param pes
   * @return
   * @throws BusinessException
   */
  public static PE AND(PE[] pes) throws BusinessException {
    return PE.build(PE.VALUE_OPERATOR_AND, pes);
  }

  /**
   * Or运算。
   * 
   * @param pe1
   * @param pe2
   * @return
   * @throws BusinessException
   */
  public static PE OR(PE pe1, PE pe2) throws BusinessException {
    return PE.build(PE.VALUE_OPERATOR_OR, pe1, pe2);
  }
  
  /**
   * Or运算。
   * 
   * @param pes
   * @return
   * @throws BusinessException
   */
  public static PE OR(PE[] pes) throws BusinessException {
    return PE.build(PE.VALUE_OPERATOR_OR, pes);
  }

  /**
   * 计算权限表达式，返回指定用户的该权限表达式的取值
   * 
   * @param user
   * @return
   * @throws BusinessException
   */
  public boolean caculate(IUser user) throws BusinessException {
    if (user == null)
      throw new BusinessException("传入参数user不可为空。");
    
    if (VALUE_OPERATOR_P.equals(operator)) {
      return user.hasPermission(permissionId);
    }
    
    if (VALUE_OPERATOR_AND.equals(operator)) {
      boolean result = true;
      for (int i = 0; i < peList.length; i++) {
        result = peList[i].caculate(user);
        if (!result)
          return false;
      }
      return result;
    }
    
    if (VALUE_OPERATOR_OR.equals(operator)) {
      boolean result = false;
      for (int i = 0; i < peList.length; i++) {
        result = peList[i].caculate(user);
        if (result)
          return true;
      }
      return result;
    }
    
    if (VALUE_OPERATOR_B.equals(operator)) {
      return this.boolValue;
    }
    
    return false;
  }
  
  /** 运算符 */
  private Integer operator;
  /** 运算符取值：单一权限 */
  private static final Integer VALUE_OPERATOR_P = new Integer(0);
  /** 运算符取值：AND */
  private static final Integer VALUE_OPERATOR_AND = new Integer(1);
  /** 运算符取值：OR */
  private static final Integer VALUE_OPERATOR_OR = new Integer(2);
  /** 运算符取值：布尔值 */
  private static final Integer VALUE_OPERATOR_B = new Integer(3);
  /** 单一权限ID */
  private String permissionId;
  /** 布尔值 */
  private boolean boolValue;
  /** 权限表达式列表 */
  private PE[] peList = null;
  
  private static PE build(Integer operator, PE pe1, PE pe2) throws BusinessException {
    if (pe1 == null)
      throw new BusinessException("传入参数pe1不可为空。");
    if (pe2 == null)
      throw new BusinessException("传入参数pe2不可为空。");
    PE pe = new PE();
    pe.operator = operator;
    pe.peList = new PE[2];
    pe.peList[0] = pe1;
    pe.peList[1] = pe2;
    return pe;
  }
  
  private static PE build(Integer operator, PE[] pes) throws BusinessException {
    for (int i = 0; i < pes.length; i++) {
      if (pes[i] == null)
        throw new BusinessException("传入参数pes[]的元素不可为空。");
    }
    PE pe = new PE();
    pe.operator = operator;
    pe.peList = pes;
    return pe;
  }

}
